home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / gpt32src.zip / INTERNAL.C < prev    next >
C/C++ Source or Header  |  1992-03-25  |  17KB  |  865 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: internal.c,v 3.26 92/03/24 22:34:29 woo Exp Locker: woo $";
  3. #endif
  4.  
  5. /* GNUPLOT - internal.c */
  6. /*
  7.  * Copyright (C) 1986, 1987, 1990, 1991, 1992   Thomas Williams, Colin Kelley
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software is provided "as is" without express or implied warranty.
  20.  * 
  21.  *
  22.  * AUTHORS
  23.  * 
  24.  *   Original Software:
  25.  *     Thomas Williams,  Colin Kelley.
  26.  * 
  27.  *   Gnuplot 2.0 additions:
  28.  *       Russell Lang, Dave Kotz, John Campbell.
  29.  *
  30.  *   Gnuplot 3.0 additions:
  31.  *       Gershon Elber and many others.
  32.  * 
  33.  * Send your comments or suggestions to 
  34.  *  info-gnuplot@ames.arc.nasa.gov.
  35.  * This is a mailing list; to join it send a note to 
  36.  *  info-gnuplot-request@ames.arc.nasa.gov.  
  37.  * Send bug reports to
  38.  *  bug-gnuplot@ames.arc.nasa.gov.
  39.  */
  40.  
  41. #include <math.h>
  42. #include <stdio.h>
  43. #include "plot.h"
  44.  
  45. BOOLEAN undefined;
  46.  
  47. char *strcpy();
  48.  
  49. struct value *pop(), *complex(), *integer();
  50. double magnitude(), angle(), real();
  51.  
  52. struct value stack[STACK_DEPTH];
  53.  
  54. int s_p = -1;   /* stack pointer */
  55.  
  56.  
  57. /*
  58.  * System V and MSC 4.0 call this when they wants to print an error message.
  59.  * Don't!
  60.  */
  61. #ifndef _CRAY
  62. #ifdef MSDOS
  63. #ifdef __TURBOC__
  64. int matherr()    /* Turbo C */
  65. #else
  66. int matherr(x)    /* MSC 5.1 */
  67. struct exception *x;
  68. #endif /* TURBOC */
  69. #else /* not MSDOS */
  70. #ifdef apollo
  71. int matherr(struct exception *x)    /* apollo */
  72. #else /* apollo */
  73. #ifdef AMIGA_LC_5_1
  74. int matherr(x)    /* AMIGA_LC_5_1 */
  75. struct exception *x;
  76. #else    /* Most everyone else (not apollo). */
  77. int matherr()
  78. #endif /* AMIGA_LC_5_1 */
  79. #endif /* apollo */
  80. #endif /* MSDOS */
  81. {
  82.     return (undefined = TRUE);        /* don't print error message */
  83. }
  84. #endif /* not _CRAY */
  85.  
  86.  
  87. reset_stack()
  88. {
  89.     s_p = -1;
  90. }
  91.  
  92.  
  93. check_stack()    /* make sure stack's empty */
  94. {
  95.     if (s_p != -1)
  96.         fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  97. }
  98.  
  99.  
  100. struct value *pop(x)
  101. struct value *x;
  102. {
  103.     if (s_p  < 0 )
  104.         int_error("stack underflow",NO_CARET);
  105.     *x = stack[s_p--];
  106.     return(x);
  107. }
  108.  
  109.  
  110. push(x)
  111. struct value *x;
  112. {
  113.     if (s_p == STACK_DEPTH - 1)
  114.         int_error("stack overflow",NO_CARET);
  115.     stack[++s_p] = *x;
  116. }
  117.  
  118.  
  119. #define ERR_VAR "undefined variable: "
  120.  
  121. f_push(x)
  122. union argument *x;        /* contains pointer to value to push; */
  123. {
  124. static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  125. struct udvt_entry *udv;
  126.  
  127.     udv = x->udv_arg;
  128.     if (udv->udv_undef) {     /* undefined */
  129.         (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  130.         int_error(err_str,NO_CARET);
  131.     }
  132.     push(&(udv->udv_value));
  133. }
  134.  
  135.  
  136. f_pushc(x)
  137. union argument *x;
  138. {
  139.     push(&(x->v_arg));
  140. }
  141.  
  142.  
  143. f_pushd1(x)
  144. union argument *x;
  145. {
  146.     push(&(x->udf_arg->dummy_values[0]));
  147. }
  148.  
  149.  
  150. f_pushd2(x)
  151. union argument *x;
  152. {
  153.     push(&(x->udf_arg->dummy_values[1]));
  154. }
  155.  
  156.  
  157. #define ERR_FUN "undefined function: "
  158.  
  159. f_call(x)  /* execute a udf */
  160. union argument *x;
  161. {
  162. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  163. register struct udft_entry *udf;
  164. struct value save_dummy;
  165.  
  166.     udf = x->udf_arg;
  167.     if (!udf->at) { /* undefined */
  168.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  169.                 udf->udf_name);
  170.         int_error(err_str,NO_CARET);
  171.     }
  172.     save_dummy = udf->dummy_values[0];
  173.     (void) pop(&(udf->dummy_values[0]));
  174.  
  175.     execute_at(udf->at);
  176.     udf->dummy_values[0] = save_dummy;
  177. }
  178.  
  179. f_call2(x)  /* execute a udf of two variables */
  180. union argument *x;
  181. {
  182. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  183. register struct udft_entry *udf;
  184. struct value save_dummy0, save_dummy1;
  185.  
  186.     udf = x->udf_arg;
  187.     if (!udf->at) { /* undefined */
  188.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  189.                 udf->udf_name);
  190.         int_error(err_str,NO_CARET);
  191.     }
  192.     save_dummy1 = udf->dummy_values[1];
  193.     save_dummy0 = udf->dummy_values[0];
  194.     (void) pop(&(udf->dummy_values[1]));
  195.     (void) pop(&(udf->dummy_values[0]));
  196.  
  197.     execute_at(udf->at);
  198.     udf->dummy_values[1] = save_dummy1;
  199.     udf->dummy_values[0] = save_dummy0;
  200. }
  201.  
  202.  
  203. static int_check(v)
  204. struct value *v;
  205. {
  206.     if (v->type != INT)
  207.         int_error("non-integer passed to boolean operator",NO_CARET);
  208. }
  209.  
  210.  
  211. f_lnot()
  212. {
  213. struct value a;
  214.     int_check(pop(&a));
  215.     push(integer(&a,!a.v.int_val) );
  216. }
  217.  
  218.  
  219. f_bnot()
  220. {
  221. struct value a;
  222.     int_check(pop(&a));
  223.     push( integer(&a,~a.v.int_val) );
  224. }
  225.  
  226.  
  227. f_bool()
  228. {            /* converts top-of-stack to boolean */
  229.     int_check(&top_of_stack);
  230.     top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  231. }
  232.  
  233.  
  234. f_lor()
  235. {
  236. struct value a,b;
  237.     int_check(pop(&b));
  238.     int_check(pop(&a));
  239.     push( integer(&a,a.v.int_val || b.v.int_val) );
  240. }
  241.  
  242. f_land()
  243. {
  244. struct value a,b;
  245.     int_check(pop(&b));
  246.     int_check(pop(&a));
  247.     push( integer(&a,a.v.int_val && b.v.int_val) );
  248. }
  249.  
  250.  
  251. f_bor()
  252. {
  253. struct value a,b;
  254.     int_check(pop(&b));
  255.     int_check(pop(&a));
  256.     push( integer(&a,a.v.int_val | b.v.int_val) );
  257. }
  258.  
  259.  
  260. f_xor()
  261. {
  262. struct value a,b;
  263.     int_check(pop(&b));
  264.     int_check(pop(&a));
  265.     push( integer(&a,a.v.int_val ^ b.v.int_val) );
  266. }
  267.  
  268.  
  269. f_band()
  270. {
  271. struct value a,b;
  272.     int_check(pop(&b));
  273.     int_check(pop(&a));
  274.     push( integer(&a,a.v.int_val & b.v.int_val) );
  275. }
  276.  
  277.  
  278. f_uminus()
  279. {
  280. struct value a;
  281.     (void) pop(&a);
  282.     switch(a.type) {
  283.         case INT:
  284.             a.v.int_val = -a.v.int_val;
  285.             break;
  286.         case CMPLX:
  287.             a.v.cmplx_val.real =
  288.                 -a.v.cmplx_val.real;
  289.             a.v.cmplx_val.imag =
  290.                 -a.v.cmplx_val.imag;
  291.     }
  292.     push(&a);
  293. }
  294.  
  295.  
  296. f_eq() /* note: floating point equality is rare because of roundoff error! */
  297. {
  298. struct value a, b;
  299.     register int result;
  300.     (void) pop(&b);
  301.     (void) pop(&a);
  302.     switch(a.type) {
  303.         case INT:
  304.             switch (b.type) {
  305.                 case INT:
  306.                     result = (a.v.int_val ==
  307.                         b.v.int_val);
  308.                     break;
  309.                 case CMPLX:
  310.                     result = (a.v.int_val ==
  311.                         b.v.cmplx_val.real &&
  312.                        b.v.cmplx_val.imag == 0.0);
  313.             }
  314.             break;
  315.         case CMPLX:
  316.             switch (b.type) {
  317.                 case INT:
  318.                     result = (b.v.int_val == a.v.cmplx_val.real &&
  319.                        a.v.cmplx_val.imag == 0.0);
  320.                     break;
  321.                 case CMPLX:
  322.                     result = (a.v.cmplx_val.real==
  323.                         b.v.cmplx_val.real &&
  324.                         a.v.cmplx_val.imag==
  325.                         b.v.cmplx_val.imag);
  326.             }
  327.     }
  328.     push(integer(&a,result));
  329. }
  330.  
  331.  
  332. f_ne()
  333. {
  334. struct value a, b;
  335.     register int result;
  336.     (void) pop(&b);
  337.     (void) pop(&a);
  338.     switch(a.type) {
  339.         case INT:
  340.             switch (b.type) {
  341.                 case INT:
  342.                     result = (a.v.int_val !=
  343.                         b.v.int_val);
  344.                     break;
  345.                 case CMPLX:
  346.                     result = (a.v.int_val !=
  347.                         b.v.cmplx_val.real ||
  348.                        b.v.cmplx_val.imag != 0.0);
  349.             }
  350.             break;
  351.         case CMPLX:
  352.             switch (b.type) {
  353.                 case INT:
  354.                     result = (b.v.int_val !=
  355.                         a.v.cmplx_val.real ||
  356.                        a.v.cmplx_val.imag != 0.0);
  357.                     break;
  358.                 case CMPLX:
  359.                     result = (a.v.cmplx_val.real !=
  360.                         b.v.cmplx_val.real ||
  361.                         a.v.cmplx_val.imag !=
  362.                         b.v.cmplx_val.imag);
  363.             }
  364.     }
  365.     push(integer(&a,result));
  366. }
  367.  
  368.  
  369. f_gt()
  370. {
  371. struct value a, b;
  372.     register int result;
  373.     (void) pop(&b);
  374.     (void) pop(&a);
  375.     switch(a.type) {
  376.         case INT:
  377.             switch (b.type) {
  378.                 case INT:
  379.                     result = (a.v.int_val >
  380.                         b.v.int_val);
  381.                     break;
  382.                 case CMPLX:
  383.                     result = (a.v.int_val >
  384.                         b.v.cmplx_val.real);
  385.             }
  386.             break;
  387.         case CMPLX:
  388.             switch (b.type) {
  389.                 case INT:
  390.                     result = (a.v.cmplx_val.real >
  391.                         b.v.int_val);
  392.                     break;
  393.                 case CMPLX:
  394.                     result = (a.v.cmplx_val.real >
  395.                         b.v.cmplx_val.real);
  396.             }
  397.     }
  398.     push(integer(&a,result));
  399. }
  400.  
  401.  
  402. f_lt()
  403. {
  404. struct value a, b;
  405.     register int result;
  406.     (void) pop(&b);
  407.     (void) pop(&a);
  408.     switch(a.type) {
  409.         case INT:
  410.             switch (b.type) {
  411.                 case INT:
  412.                     result = (a.v.int_val <
  413.                         b.v.int_val);
  414.                     break;
  415.                 case CMPLX:
  416.                     result = (a.v.int_val <
  417.                         b.v.cmplx_val.real);
  418.             }
  419.             break;
  420.         case CMPLX:
  421.             switch (b.type) {
  422.                 case INT:
  423.                     result = (a.v.cmplx_val.real <
  424.                         b.v.int_val);
  425.                     break;
  426.                 case CMPLX:
  427.                     result = (a.v.cmplx_val.real <
  428.                         b.v.cmplx_val.real);
  429.             }
  430.     }
  431.     push(integer(&a,result));
  432. }
  433.  
  434.  
  435. f_ge()
  436. {
  437. struct value a, b;
  438.     register int result;
  439.     (void) pop(&b);
  440.     (void) pop(&a);
  441.     switch(a.type) {
  442.         case INT:
  443.             switch (b.type) {
  444.                 case INT:
  445.                     result = (a.v.int_val >=
  446.                         b.v.int_val);
  447.                     break;
  448.                 case CMPLX:
  449.                     result = (a.v.int_val >=
  450.                         b.v.cmplx_val.real);
  451.             }
  452.             break;
  453.         case CMPLX:
  454.             switch (b.type) {
  455.                 case INT:
  456.                     result = (a.v.cmplx_val.real >=
  457.                         b.v.int_val);
  458.                     break;
  459.                 case CMPLX:
  460.                     result = (a.v.cmplx_val.real >=
  461.                         b.v.cmplx_val.real);
  462.             }
  463.     }
  464.     push(integer(&a,result));
  465. }
  466.  
  467.  
  468. f_le()
  469. {
  470. struct value a, b;
  471.     register int result;
  472.     (void) pop(&b);
  473.     (void) pop(&a);
  474.     switch(a.type) {
  475.         case INT:
  476.             switch (b.type) {
  477.                 case INT:
  478.                     result = (a.v.int_val <=
  479.                         b.v.int_val);
  480.                     break;
  481.                 case CMPLX:
  482.                     result = (a.v.int_val <=
  483.                         b.v.cmplx_val.real);
  484.             }
  485.             break;
  486.         case CMPLX:
  487.             switch (b.type) {
  488.                 case INT:
  489.                     result = (a.v.cmplx_val.real <=
  490.                         b.v.int_val);
  491.                     break;
  492.                 case CMPLX:
  493.                     result = (a.v.cmplx_val.real <=
  494.                         b.v.cmplx_val.real);
  495.             }
  496.     }
  497.     push(integer(&a,result));
  498. }
  499.  
  500.  
  501. f_plus()
  502. {
  503. struct value a, b, result;
  504.     (void) pop(&b);
  505.     (void) pop(&a);
  506.     switch(a.type) {
  507.         case INT:
  508.             switch (b.type) {
  509.                 case INT:
  510.                     (void) integer(&result,a.v.int_val +
  511.                         b.v.int_val);
  512.                     break;
  513.                 case CMPLX:
  514.                     (void) complex(&result,a.v.int_val +
  515.                         b.v.cmplx_val.real,
  516.                        b.v.cmplx_val.imag);
  517.             }
  518.             break;
  519.         case CMPLX:
  520.             switch (b.type) {
  521.                 case INT:
  522.                     (void) complex(&result,b.v.int_val +
  523.                         a.v.cmplx_val.real,
  524.                        a.v.cmplx_val.imag);
  525.                     break;
  526.                 case CMPLX:
  527.                     (void) complex(&result,a.v.cmplx_val.real+
  528.                         b.v.cmplx_val.real,
  529.                         a.v.cmplx_val.imag+
  530.                         b.v.cmplx_val.imag);
  531.             }
  532.     }
  533.     push(&result);
  534. }
  535.  
  536.  
  537. f_minus()
  538. {
  539. struct value a, b, result;
  540.     (void) pop(&b);
  541.     (void) pop(&a);        /* now do a - b */
  542.     switch(a.type) {
  543.         case INT:
  544.             switch (b.type) {
  545.                 case INT:
  546.                     (void) integer(&result,a.v.int_val -
  547.                         b.v.int_val);
  548.                     break;
  549.                 case CMPLX:
  550.                     (void) complex(&result,a.v.int_val -
  551.                         b.v.cmplx_val.real,
  552.                        -b.v.cmplx_val.imag);
  553.             }
  554.             break;
  555.         case CMPLX:
  556.             switch (b.type) {
  557.                 case INT:
  558.                     (void) complex(&result,a.v.cmplx_val.real -
  559.                         b.v.int_val,
  560.                         a.v.cmplx_val.imag);
  561.                     break;
  562.                 case CMPLX:
  563.                     (void) complex(&result,a.v.cmplx_val.real-
  564.                         b.v.cmplx_val.real,
  565.                         a.v.cmplx_val.imag-
  566.                         b.v.cmplx_val.imag);
  567.             }
  568.     }
  569.     push(&result);
  570. }
  571.  
  572.  
  573. f_mult()
  574. {
  575. struct value a, b, result;
  576.     (void) pop(&b);
  577.     (void) pop(&a);    /* now do a*b */
  578.  
  579.     switch(a.type) {
  580.         case INT:
  581.             switch (b.type) {
  582.                 case INT:
  583.                     (void) integer(&result,a.v.int_val *
  584.                         b.v.int_val);
  585.                     break;
  586.                 case CMPLX:
  587.                     (void) complex(&result,a.v.int_val *
  588.                         b.v.cmplx_val.real,
  589.                         a.v.int_val *
  590.                         b.v.cmplx_val.imag);
  591.             }
  592.             break;
  593.         case CMPLX:
  594.             switch (b.type) {
  595.                 case INT:
  596.                     (void) complex(&result,b.v.int_val *
  597.                         a.v.cmplx_val.real,
  598.                         b.v.int_val *
  599.                         a.v.cmplx_val.imag);
  600.                     break;
  601.                 case CMPLX:
  602.                     (void) complex(&result,a.v.cmplx_val.real*
  603.                         b.v.cmplx_val.real-
  604.                         a.v.cmplx_val.imag*
  605.                         b.v.cmplx_val.imag,
  606.                         a.v.cmplx_val.real*
  607.                         b.v.cmplx_val.imag+
  608.                         a.v.cmplx_val.imag*
  609.                         b.v.cmplx_val.real);
  610.             }
  611.     }
  612.     push(&result);
  613. }
  614.  
  615.  
  616. f_div()
  617. {
  618. struct value a, b, result;
  619. register double square;
  620.     (void) pop(&b);
  621.     (void) pop(&a);    /* now do a/b */
  622.  
  623.     switch(a.type) {
  624.         case INT:
  625.             switch (b.type) {
  626.                 case INT:
  627.                     if (b.v.int_val)
  628.                       (void) integer(&result,a.v.int_val /
  629.                         b.v.int_val);
  630.                     else {
  631.                       (void) integer(&result,0);
  632.                       undefined = TRUE;
  633.                     }
  634.                     break;
  635.                 case CMPLX:
  636.                     square = b.v.cmplx_val.real*
  637.                         b.v.cmplx_val.real +
  638.                         b.v.cmplx_val.imag*
  639.                         b.v.cmplx_val.imag;
  640.                     if (square)
  641.                         (void) complex(&result,a.v.int_val*
  642.                         b.v.cmplx_val.real/square,
  643.                         -a.v.int_val*
  644.                         b.v.cmplx_val.imag/square);
  645.                     else {
  646.                         (void) complex(&result,0.0,0.0);
  647.                         undefined = TRUE;
  648.                     }
  649.             }
  650.             break;
  651.         case CMPLX:
  652.             switch (b.type) {
  653.                 case INT:
  654.                     if (b.v.int_val)
  655.                       
  656.                       (void) complex(&result,a.v.cmplx_val.real/
  657.                         b.v.int_val,
  658.                         a.v.cmplx_val.imag/
  659.                         b.v.int_val);
  660.                     else {
  661.                         (void) complex(&result,0.0,0.0);
  662.                         undefined = TRUE;
  663.                     }
  664.                     break;
  665.                 case CMPLX:
  666.                     square = b.v.cmplx_val.real*
  667.                         b.v.cmplx_val.real +
  668.                         b.v.cmplx_val.imag*
  669.                         b.v.cmplx_val.imag;
  670.                     if (square)
  671.                     (void) complex(&result,(a.v.cmplx_val.real*
  672.                         b.v.cmplx_val.real+
  673.                         a.v.cmplx_val.imag*
  674.                         b.v.cmplx_val.imag)/square,
  675.                         (a.v.cmplx_val.imag*
  676.                         b.v.cmplx_val.real-
  677.                         a.v.cmplx_val.real*
  678.                         b.v.cmplx_val.imag)/
  679.                             square);
  680.                     else {
  681.                         (void) complex(&result,0.0,0.0);
  682.                         undefined = TRUE;
  683.                     }
  684.             }
  685.     }
  686.     push(&result);
  687. }
  688.  
  689.  
  690. f_mod()
  691. {
  692. struct value a, b;
  693.     (void) pop(&b);
  694.     (void) pop(&a);    /* now do a%b */
  695.  
  696.     if (a.type != INT || b.type != INT)
  697.         int_error("can only mod ints",NO_CARET);
  698.     if (b.v.int_val)
  699.         push(integer(&a,a.v.int_val % b.v.int_val));
  700.     else {
  701.         push(integer(&a,0));
  702.         undefined = TRUE;
  703.     }
  704. }
  705.  
  706.  
  707. f_power()
  708. {
  709. struct value a, b, result;
  710. register int i, t, count;
  711. register double mag, ang;
  712.     (void) pop(&b);
  713.     (void) pop(&a);    /* now find a**b */
  714.  
  715.     switch(a.type) {
  716.         case INT:
  717.             switch (b.type) {
  718.                 case INT:
  719.                     count = abs(b.v.int_val);
  720.                     t = 1;
  721.                     for(i = 0; i < count; i++)
  722.                         t *= a.v.int_val;
  723.                     if (b.v.int_val >= 0)
  724.                         (void) integer(&result,t);
  725.                     else
  726.                       if (t != 0)
  727.                         (void) complex(&result,1.0/t,0.0);
  728.                       else {
  729.                          undefined = TRUE;
  730.                          (void) complex(&result, 0.0, 0.0);
  731.                       }
  732.                     break;
  733.                 case CMPLX:
  734.                     mag =
  735.                       pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  736.                     if (b.v.cmplx_val.real < 0.0)
  737.                       if (mag != 0.0)
  738.                         mag = 1.0/mag;
  739.                       else 
  740.                         undefined = TRUE;
  741.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  742.                     ang = b.v.cmplx_val.real*angle(&a) +
  743.                           b.v.cmplx_val.imag*log(magnitude(&a));
  744.                     (void) complex(&result,mag*cos(ang),
  745.                         mag*sin(ang));
  746.             }
  747.             break;
  748.         case CMPLX:
  749.             switch (b.type) {
  750.                 case INT:
  751.                     if (a.v.cmplx_val.imag == 0.0) {
  752.                         mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  753.                         if (b.v.int_val < 0)
  754.                           if (mag != 0.0)
  755.                             mag = 1.0/mag;
  756.                           else 
  757.                             undefined = TRUE;
  758.                         (void) complex(&result,mag,0.0);
  759.                     }
  760.                     else {
  761.                         /* not so good, but...! */
  762.                         mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  763.                         if (b.v.int_val < 0)
  764.                           if (mag != 0.0)
  765.                             mag = 1.0/mag;
  766.                           else 
  767.                             undefined = TRUE;
  768.                         ang = angle(&a)*b.v.int_val;
  769.                         (void) complex(&result,mag*cos(ang),
  770.                             mag*sin(ang));
  771.                     }
  772.                     break;
  773.                 case CMPLX:
  774.                     mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  775.                     if (b.v.cmplx_val.real < 0.0)
  776.                       if (mag != 0.0)
  777.                         mag = 1.0/mag;
  778.                       else 
  779.                         undefined = TRUE;
  780.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  781.                     ang = b.v.cmplx_val.real*angle(&a) +
  782.                           b.v.cmplx_val.imag*log(magnitude(&a));
  783.                     (void) complex(&result,mag*cos(ang),
  784.                         mag*sin(ang));
  785.             }
  786.     }
  787.     push(&result);
  788. }
  789.  
  790.  
  791. f_factorial()
  792. {
  793. struct value a;
  794. register int i;
  795. register double val;
  796.  
  797.     (void) pop(&a);    /* find a! (factorial) */
  798.  
  799.     switch (a.type) {
  800.         case INT:
  801.             val = 1.0;
  802.             for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  803.                 val *= i;
  804.             break;
  805.         default:
  806.             int_error("factorial (!) argument must be an integer",
  807.             NO_CARET);
  808.         }
  809.  
  810.     push(complex(&a,val,0.0));
  811.             
  812. }
  813.  
  814.  
  815. int
  816. f_jump(x)
  817. union argument *x;
  818. {
  819.     return(x->j_arg);
  820. }
  821.  
  822.  
  823. int
  824. f_jumpz(x)
  825. union argument *x;
  826. {
  827. struct value a;
  828.     int_check(&top_of_stack);
  829.     if (top_of_stack.v.int_val) {    /* non-zero */
  830.         (void) pop(&a);
  831.         return 1;                /* no jump */
  832.     }
  833.     else
  834.         return(x->j_arg);        /* leave the argument on TOS */
  835. }
  836.  
  837.  
  838. int
  839. f_jumpnz(x)
  840. union argument *x;
  841. {
  842. struct value a;
  843.     int_check(&top_of_stack);
  844.     if (top_of_stack.v.int_val)    /* non-zero */
  845.         return(x->j_arg);        /* leave the argument on TOS */
  846.     else {
  847.         (void) pop(&a);
  848.         return 1;                /* no jump */
  849.     }
  850. }
  851.  
  852.  
  853. int
  854. f_jtern(x)
  855. union argument *x;
  856. {
  857. struct value a;
  858.  
  859.     int_check(pop(&a));
  860.     if (a.v.int_val)
  861.         return(1);                /* no jump; fall through to TRUE code */
  862.     else
  863.         return(x->j_arg);        /* go jump to FALSE code */
  864. }
  865.